//工艺价格表
<script setup lang="ts">
// ----------------------- 导入相关依赖 -----------------------
import {nextTick, onMounted, onUnmounted, reactive, ref} from "vue";
import {ElMessage, FormInstance} from "element-plus";
import SysDialog from "@/components/dialog/SysDialog.vue";
import useDialog from "@/hooks/useDialog";
import useInstance from "@/hooks/useInstance";
import {addSonApi, deleteSonApi, editSonApi, getSonListApi, exportProcessSonApi, importProcessSonApi, downloadProcessSonTemplateApi} from "@/api/process";
// 物料分类精简类别，用于树形结构展示
import {getSimpleListApi} from "@/api/process/index.ts";
import {Process, ProcessSon, ProcessListParam} from "@/api/process/type.ts";
// 单位列表，用于物料单位下拉框
import {getUnitSimpleListApi} from "@/api/unit/index.ts";
// 图标组件
import {Search, Refresh, Plus, Edit, Delete, Download, Upload} from '@element-plus/icons-vue'
import TreeSelect from "@/components/TreeSelect/index.vue";
import {Unit} from "@/api/unit/type.ts";

// ----------------------- 组件状态定义 -----------------------
const {dialog, onShow, onClose} = useDialog()
const {global} = useInstance()

// 表格高度自适应
const tableHeight = ref(0)

// ----------------------- 表格相关 -----------------------
const tableData = ref([])
const loading = ref(false)
const paginationData = reactive({
  total: 0,
  currentPage: 1,
  pageSize: 10
})


// ----------------------- 查询表单相关 -----------------------
const searchForm = reactive<ProcessListParam>({
  processCode: undefined,
  processName: undefined,
  isActive: undefined,
  productName: undefined,
  pid: undefined,
  page: 1,
  limit: 10
})

// 查询方法
const search = () => {
  paginationData.currentPage = 1
  getTableData()
}

// 重置查询
const reset = () => {
  searchForm.processCode = undefined
  searchForm.processName = undefined
  searchForm.isActive = undefined
  searchForm.productName = undefined
  searchForm.pid = undefined
  search()
}

// 修复其他类型错误
const initPage = async () => {
  searchForm.page = 1;
  searchForm.limit = 10;
  searchForm.processCode = undefined
  searchForm.processName = undefined
  searchForm.isActive = undefined
  searchForm.productName = undefined
  searchForm.pid = undefined
  await getTableData();
}

// ----------------------- 表格数据处理 -----------------------
const getTableData = async () => {
  loading.value = true
  try {
    searchForm.page = paginationData.currentPage
    searchForm.limit = paginationData.pageSize
    let res = await getSonListApi(searchForm)
    if (res && res.data) {
      tableData.value = res.data.list
      paginationData.total = res.data.total
    }
  } catch (error) {
    console.error('获取表格数据失败:', error)
  } finally {
    loading.value = false
  }
}

// ----------------------- 新增/编辑表单相关 -----------------------
const addFormRef = ref<FormInstance>()
const addForm = reactive<ProcessSon>({
  id: undefined,
  pid: undefined,
  productName: undefined,
  cost: undefined,
  heightMin: undefined,
  heightMax: undefined,
  thicknessMin: undefined,
  thicknessMax: undefined,
  material: undefined,
  number: undefined,
  height: undefined,
  thickness: undefined,
  isDelete: 0
})

// 表单校验规则
const rules = {
  processCode: [{required: true, message: '请输入工艺编码', trigger: 'blur'}],
  processName: [{required: true, message: '请输入工艺名称', trigger: 'blur'}],
  isActive: [{required: true, message: '请选择是否激活', trigger: 'change'}],
  pid: [{required: true, message: '请选择工艺', trigger: 'change'}],

}

// 打开新增弹框
const openAdd = () => {
  dialog.title = '新增工艺价格'
  dialog.width = 900
  dialog.height = 400
  onShow()
}

// 打开编辑弹框
const openEdit = (row: ProcessSon) => {
  dialog.title = '编辑工艺价格'
  dialog.width = 900
  dialog.height = 400
  nextTick(() => {
    Object.assign(addForm, row)
  })
  onShow()
}

// 关闭弹框
const closeDialog = () => {
  addFormRef.value?.resetFields()
  Object.assign(addForm, {
    id: undefined,
    pid: undefined,
    productName: undefined,
    cost: undefined,
    heightMin: undefined,
    heightMax: undefined,
    thicknessMin: undefined,
    thicknessMax: undefined,
    material: undefined,
    number: undefined,
    height: undefined,
    thickness: undefined,
    isDelete: 0
  })
  onClose()
}

// 提交表单
const submit = async () => {
  await addFormRef.value?.validate()
  try {
    if (addForm.id) {
      await editSonApi(addForm)
      ElMessage.success('编辑成功')
    } else {
      await addSonApi(addForm)
      ElMessage.success('新增成功')
    }
    getTableData()
    closeDialog()
  } catch (error) {
    console.error('提交失败:', error)
  }
}

// ----------------------- 删除相关 -----------------------
const deleteOne = async (id: number) => {
  const confirm = await global.$myConfirm('确定要删除该工艺吗？')
  console.error("提示返回：" + confirm)
  if (confirm) {
    try {
      await deleteSonApi(id)
      ElMessage.success('删除成功')
      if (tableData.value.length === 1 && paginationData.currentPage > 1) {
        paginationData.currentPage--
      }
      getTableData()
    } catch (error) {
      console.error('删除失败:', error)
    }
  }
}


// ----------------------- 树形数据处理 -----------------------
// 上级分类选择器的数据
const parentOptions = ref<any[]>([])

/**
 * 获取分类列表数据
 * 用于新增/编辑表单中的物料的分类选择
 */
const getParentCategories = async () => {
  try {
    const res = await getSimpleListApi()
    if (res?.data) {
      // 直接使用处理后的树形数据
      parentOptions.value = handleParentTree(res.data)
    }
  } catch (error) {
    console.error('获取分类列表失败:', error)
    ElMessage.error('获取分类列表失败')
  }
}

/**
 * 处理分类树形数据
 * @param data 原始数据
 * @returns 处理后的树形数据
 */
const handleParentTree = (data: any[]) => {
  const map = new Map()
  const result: any[] = []

  // 初始化映射表
  data.forEach(item => {
    map.set(item.id, {
      id: item.id,
      value: item.id,
      label: item.categoryName,
      children: []
    })
  })

  // 构建树形结构
  data.forEach(item => {
    const node = map.get(item.id)
    if (item.parentId === "0") {
      // 顶级分类直接加入结果数组
      result.push(node)
    } else {
      const parent = map.get(item.parentId)
      if (parent) {
        parent.children.push(node)
      }
    }
  })
  return result
}


// ----------------------- 左侧筛选树形数据处理 -----------------------
// 当前选中的分类ID，用于树形筛选
const currentCategoryId = ref<number>()

// 定义树节点类型
interface TreeNode {
  id: string;
  categoryName: string;
  parentId: string;
  children: TreeNode[];
}

// 左侧筛选树形数据
const treeData = ref<TreeNode[]>([])
/**
 * 获取侧筛选树形数据
 */
const getTreeData = async () => {
    const res = await getSimpleListApi()
      treeData.value = res.data 
}

/**
 * 树节点点击事件处理
 */
const handleTreeNodeClick = async (data: any) => {
  // 处理虚拟顶级节点点击
    currentCategoryId.value = data.id;
    searchForm.pid = data.id;
  // 重置分页和搜索条件
  searchForm.page = 1;
  searchForm.limit = 10;
  searchForm.processCode = undefined
  searchForm.processName = undefined
  searchForm.isActive = undefined
  searchForm.productName = undefined
  await getTableData();
}


// ---------------------- 物料单位，用于物料单位下拉框 ----------------------
const unitOptions = ref<Unit[]>([])

// 获取单位数据
const getUnitData = async () => {
  try {
    const res = await getUnitSimpleListApi()
    if (res?.data) {
      unitOptions.value = res.data
    }
  } catch (error) {
    console.error('获取物料单位数据失败:', error)
    ElMessage.error('获取物料单位数据失败')
  }
}
const pList =  ref([] as Process[]) //  // 

// ----------------------- 生命周期钩子 -----------------------
onMounted(async () => {

  const res = await getSimpleListApi()
  pList.value = res.data
  console.log("ppppp:"+pList);
  
  getTreeData()
  // 表格数据
  getTableData()
  nextTick(() => {
    tableHeight.value = window.innerHeight - 260
  })
  // 分类选择器的数据
  getParentCategories();
  // 物料单位，下拉框数据
  getUnitData();
})

// 监听窗口大小变化
const handleResize = () => {
  nextTick(() => {
    tableHeight.value = window.innerHeight - 260
  })
}

onMounted(() => {
  window.addEventListener('resize', handleResize)
})

onUnmounted(() => {
  window.removeEventListener('resize', handleResize)
})

// 添加导入导出相关方法
// 导出数据
const exportData = async () => {
  try {
    loading.value = true
    const response = await exportProcessSonApi({
      pid: searchForm.pid,
      productName: searchForm.productName
    })
    
    // 创建Blob对象并下载
    const blob = new Blob([response.data])
    const url = window.URL.createObjectURL(blob)
    const link = document.createElement('a')
    link.href = url
    link.download = '工序子项数据.xlsx'
    link.click()
    window.URL.revokeObjectURL(url)
    ElMessage.success('导出成功')
  } catch (error) {
    console.error('导出失败:', error)
    ElMessage.error('导出失败')
  } finally {
    loading.value = false
  }
}

// 在导入相关的部分添加下载模板方法
const downloadTemplate = async () => {
  try {
    loading.value = true
    const response = await downloadProcessSonTemplateApi()
    
    // 创建Blob对象并下载
    const blob = new Blob([response.data])
    const url = window.URL.createObjectURL(blob)
    const link = document.createElement('a')
    link.href = url
    link.download = '工序子项导入模板.xlsx'
    link.click()
    window.URL.revokeObjectURL(url)
    ElMessage.success('模板下载成功')
  } catch (error) {
    console.error('模板下载失败:', error)
    ElMessage.error('模板下载失败')
  } finally {
    loading.value = false
  }
}

// 导入相关
const uploadRef = ref()
const handleImport = () => {
  uploadRef.value.click()
}

const handleFileChange = async (e: Event) => {
  const target = e.target as HTMLInputElement
  if (!target.files || target.files.length === 0) {
    return
  }
  
  const file = target.files[0]
  if (!/\.(xlsx|xls)$/.test(file.name.toLowerCase())) {
    ElMessage.error('只能上传Excel文件')
    return
  }
  
  const formData = new FormData()
  formData.append('file', file)
  
  try {
    loading.value = true
    const res = await importProcessSonApi(formData)
    ElMessage.success(res.message || '导入成功')
    // 刷新数据
    getTableData()
  } catch (error) {
    console.error('导入失败:', error)
    ElMessage.error('导入失败')
  } finally {
    // 清空文件选择
    target.value = ''
    loading.value = false
  }
}
</script>

<template>
  <el-main class="process-son-main">
    <div class="main-container">

    
      <el-row :gutter="20">
        <!-- 左侧树形菜单 -->
        <el-col :span="4">
          <el-card class="tree-card" shadow="hover">
            <div class="tree-header">
              <i class="el-icon-menu"></i>
              <span>工艺分类</span>
            </div>
            <TreeSelect
              :data="treeData"
              :props="{
                children: 'children',
                label: 'processName'
              }"
              placeholder="请输入分类名称"
              @node-click="handleTreeNodeClick"
              class="process-tree"
            />
          </el-card>
        </el-col>

        <!-- 右侧内容区 -->
        <el-col :span="20">
          <!-- 查询表单区域 -->
          <el-card class="search-card" shadow="hover">
            <el-form :inline="true" :model="searchForm" class="search-form">
              <el-form-item label="产品名称">
                <el-input 
                  v-model="searchForm.productName" 
                  placeholder="请输入产品名称" 
                  prefix-icon="Search"
                  clearable
                />
              </el-form-item>
              <el-form-item class="search-buttons">
                <el-button type="primary" :icon="Search" @click="search" class="search-btn">
                  查询
                </el-button>
                <el-button :icon="Refresh" @click="reset" class="reset-btn">
                  重置
                </el-button>
                <el-button type="success" :icon="Plus" @click="openAdd" class="add-btn">
                  新增
                </el-button>
                <el-button type="success" :icon="Upload" @click="handleImport" class="import-btn">导入</el-button>
                <el-button type="warning" :icon="Download" @click="downloadTemplate" class="template-btn">下载模板</el-button>
                <el-button type="info" :icon="Download" @click="exportData" class="export-btn">导出</el-button>
                <input
                  type="file"
                  ref="uploadRef"
                  style="display: none"
                  accept=".xlsx,.xls"
                  @change="handleFileChange"
                />
              </el-form-item>
            </el-form>
          </el-card>

          <!-- 表格区域 -->
          <el-card class="table-card" shadow="hover">
            <el-table
              v-loading="loading"
              :data="tableData"
              border
              :height="tableHeight"
              class="data-table"
            >
              <el-table-column type="index" label="序号" width="70" align="center"/>
              <el-table-column prop="productName" label="产品名称" min-width="120" align="center"/>
              <el-table-column prop="material" label="材质" min-width="120" align="center"/>

              <el-table-column label="高度范围" min-width="150" align="center">
                <template #default="scope">
                  <div class="range-value">
                    <span>{{ scope.row.heightMin || 0 }}</span>
                    <span class="range-separator">-</span>
                    <span>{{ scope.row.heightMax || 0 }}</span>
                  </div>
                </template>
              </el-table-column>
              
              <el-table-column label="厚度范围" min-width="150" align="center">
                <template #default="scope">
                  <div class="range-value">
                    <span>{{ scope.row.thicknessMin || 0 }}</span>
                    <span class="range-separator">-</span>
                    <span>{{ scope.row.thicknessMax || 0 }}</span>
                  </div>
                </template>
              </el-table-column>
              
              <el-table-column prop="cost" label="单价" min-width="100" align="center">
                <template #default="scope">
                  <span class="cost-value">{{ scope.row.cost || '-' }}</span>
                </template>
              </el-table-column>

              <el-table-column prop="material" label="材料" min-width="120" align="center">
                <template #default="scope">
                  <el-tag size="small" type="success" effect="light">{{ scope.row.material || '-' }}</el-tag>
                </template>
              </el-table-column>
              
              <el-table-column prop="number" label="次数" min-width="90" align="center">
                <template #default="scope">
                  <span class="times-value">{{ scope.row.number || '0' }}</span>
                </template>
              </el-table-column>
              
              <el-table-column label="操作" width="160" fixed="right" align="center">
                <template #default="scope">
                  <div class="action-buttons">
                    <el-button type="primary" size="small" :icon="Edit" @click="openEdit(scope.row)" class="edit-btn">
                      编辑
                    </el-button>
                    <el-button type="danger" size="small" :icon="Delete" @click="deleteOne(scope.row.id)" class="delete-btn">
                      删除
                    </el-button>
                  </div>
                </template>
              </el-table-column>
            </el-table>

            <!-- 分页 -->
            <el-pagination
              v-model:current-page="paginationData.currentPage"
              v-model:page-size="paginationData.pageSize"
              :page-sizes="[10, 20, 50]"
              :total="paginationData.total"
              layout="total, sizes, prev, pager, next"
              class="pagination"
              @size-change="getTableData"
              @current-change="getTableData"
            />
          </el-card>
        </el-col>
      </el-row>
    </div>

    <!-- 新增/编辑弹框 -->
    <sys-dialog
      :title="dialog.title"
      :width="dialog.width"
      :visible="dialog.visible"
      :height="dialog.height"
      @onClose="closeDialog"
      @onConfirm="submit"
    >
      <template #content>
        <div class="dialog-content">
          <el-form
            ref="addFormRef"
            :model="addForm"
            :rules="rules"
            label-width="90px"
            class="add-form"
          >
            <el-card class="form-card" shadow="never">
              <template #header>
                <div class="form-header">
                  <span>基本信息</span>
                </div>
              </template>
              <el-row :gutter="20">
                <el-col :span="12">
                  <el-form-item label="产品名称" prop="productName">
                    <el-input v-model="addForm.productName" placeholder="请输入产品名称" />
                  </el-form-item>
                </el-col>
                <el-col :span="12">
                  <el-form-item label="工艺" prop="pid">
                    <el-select v-model="addForm.pid" placeholder="请选择工艺" class="full-width">
                      <el-option
                        v-for="item in pList"
                        :key="item.id"
                        :label="item.processName"
                        :value="item.id">
                      </el-option>
                    </el-select>          
                  </el-form-item>
                </el-col>
              </el-row>
              <el-row :gutter="20">
                <el-col :span="12">
                  <el-form-item label="材质" prop="material">
                    <el-input v-model="addForm.material" placeholder="请输入材质" />
                  </el-form-item>
                </el-col>
              </el-row>
            </el-card>
            
            <el-card class="form-card" shadow="never">
              <template #header>
                <div class="form-header">
                  <span>成本信息</span>
                </div>
              </template>
              <el-row :gutter="20">
                <el-col :span="12">
                  <el-form-item label="单价">
                    <el-input v-model="addForm.cost" placeholder="请输入单价" type="number" />
                  </el-form-item>
                </el-col>
                <el-col :span="12">
                  <el-form-item label="数量">
                    <el-input v-model="addForm.number" placeholder="请输入数量" type="number" />
                  </el-form-item>
                </el-col>
              </el-row>
            </el-card>
           
            <el-card class="form-card" shadow="never">
              <template #header>
                <div class="form-header">
                  <span>尺寸规格</span>
                </div>
              </template> 
              <el-row :gutter="20">
                <el-col :span="12">
                  <el-form-item label="最小高度">
                    <el-input-number
                      v-model="addForm.heightMin"
                      :precision="2"
                      :step="0.1"
                      :min="0"
                      placeholder="请输入最小高度"
                      class="full-width"
                    />
                  </el-form-item>
                </el-col>
                <el-col :span="12">
                  <el-form-item label="最大高度(包含)">
                    <el-input-number
                      v-model="addForm.heightMax"
                      :precision="2"
                      :step="0.1"
                      :min="0"
                      placeholder="请输入最大高度"
                      class="full-width"
                    />
                  </el-form-item>
                </el-col>
              </el-row>

              <el-row :gutter="20">
                <el-col :span="12">
                  <el-form-item label="最小厚度">
                    <el-input-number
                      v-model="addForm.thicknessMin"
                      :precision="2"
                      :step="0.1"
                      :min="0"
                      placeholder="请输入最小厚度"
                      class="full-width"
                    />
                  </el-form-item>
                </el-col>
                <el-col :span="12">
                  <el-form-item label="最大厚度(包含)">
                    <el-input-number
                      v-model="addForm.thicknessMax"
                      :precision="2"
                      :step="0.1"
                      :min="0"
                      placeholder="请输入最大厚度"
                      class="full-width"
                    />
                  </el-form-item>
                </el-col>
              </el-row>
            </el-card>
          </el-form>
        </div>
      </template>
    </sys-dialog>
  </el-main>
</template>

<style scoped lang="scss">
.process-son-main {
  padding: 0;
}

.main-container {
  padding: 20px;
  background-color: #f5f7fa;
  min-height: calc(100vh - 60px);
}

.page-header {
  margin-bottom: 20px;
  
  h2 {
    margin: 0;
    font-size: 22px;
    font-weight: 600;
    color: #303133;
  }
  
  .page-description {
    margin-top: 8px;
    color: #909399;
    font-size: 14px;
  }
}

.tree-card {
  border-radius: 8px;
  height: calc(100vh - 100px);
  
  .tree-header {
    padding: 12px 0;
    margin-bottom: 10px;
    display: flex;
    align-items: center;
    font-size: 16px;
    font-weight: 600;
    color: #67c23a;
    border-bottom: 1px solid #e1f3d8;
    
    i {
      margin-right: 8px;
    }
  }
  
  .process-tree {
    height: calc(100vh - 160px);
    overflow: auto;
    
    :deep(.el-tree-node__content) {
      height: 36px;
      
      &:hover {
        background-color: #f0f9eb;
      }
    }
    
    :deep(.el-tree-node.is-current > .el-tree-node__content) {
      background-color: #e1f3d8;
      color: #67c23a;
    }
  }
}

.search-card {
  margin-bottom: 20px;
  border-radius: 8px;
  transition: all 0.3s;
  
  :deep(.el-card__body) {
    padding: 15px 20px;
  }
}

.search-form {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  
  .el-form-item {
    margin-bottom: 0;
    margin-right: 16px;
  }
  
  .search-buttons {
    margin-left: auto;
    
    .el-button {
      margin-left: 8px;
      transition: all 0.3s;
      
      &:first-child {
        margin-left: 0;
      }
    }
    
    .search-btn {
      background: linear-gradient(135deg, #1989fa, #0056b3);
      border: none;
      
      &:hover {
        opacity: 0.9;
        transform: translateY(-2px);
        box-shadow: 0 4px 12px rgba(25, 137, 250, 0.3);
      }
    }
    
    .add-btn {
      background: linear-gradient(135deg, #67c23a, #409eff);
      border: none;
      
      &:hover {
        opacity: 0.9;
        transform: translateY(-2px);
        box-shadow: 0 4px 12px rgba(103, 194, 58, 0.3);
      }
    }
    
    .reset-btn:hover {
      transform: translateY(-2px);
      box-shadow: 0 4px 12px rgba(144, 147, 153, 0.2);
    }
  }
}

.table-card {
  border-radius: 8px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
  height: calc(100vh - 180px);
  margin-bottom: 0;
  
  :deep(.el-card__body) {
    padding: 0;
    height: 100%;
    display: flex;
    flex-direction: column;
  }
}

.data-table {
  border-radius: 4px;
  flex: 1;
  
  :deep(.el-table__header-wrapper) {
    th {
      background-color: #f2f6fc;
      font-weight: 600;
    }
  }
  
  :deep(.el-table__row) {
    &:hover {
      td {
        background-color: #ecf5ff;
      }
    }
  }
  
  .range-value {
    display: flex;
    justify-content: center;
    align-items: center;
    
    .range-separator {
      margin: 0 6px;
      color: #909399;
    }
  }
  
  .cost-value {
    font-weight: 600;
    color: #409eff;
  }
  
  .times-value {
    font-weight: 600;
    color: #ff9800;
  }
  
  .action-buttons {
    display: flex;
    justify-content: center;
    
    .el-button {
      padding: 6px 10px;
      transition: all 0.3s;
      
      &:hover {
        transform: translateY(-2px);
      }
    }
    
    .edit-btn {
      margin-right: 10px;
    }
  }
}

.pagination {
  padding: 15px 20px;
  justify-content: flex-end;
  background: #fff;
  border-radius: 0 0 8px 8px;
}

.dialog-content {
  padding: 10px;
}

.add-form {
  .form-card {
    margin-bottom: 15px;
    border-radius: 8px;
    transition: all 0.3s;
    overflow: hidden;
    border: 1px solid #ebeef5;
    
    &:last-child {
      margin-bottom: 0;
    }
    
    :deep(.el-card__header) {
      padding: 10px 15px;
      background: linear-gradient(90deg, #f0f9eb, #e1f3d8);
      border-bottom: 1px solid #e1f3d8;
    }
    
    .form-header {
      font-size: 16px;
      font-weight: 600;
      color: #67c23a;
    }
  }
  
  :deep(.el-input), :deep(.el-select), :deep(.el-input-number) {
    width: 100%;
  }
  
  :deep(.el-input__wrapper), :deep(.el-textarea__inner) {
    box-shadow: 0 0 0 1px #dcdfe6 inset;
    
    &:hover {
      box-shadow: 0 0 0 1px #c0c4cc inset;
    }
    
    &.is-focus {
      box-shadow: 0 0 0 1px #67c23a inset;
    }
  }
  
  :deep(.el-form-item__label) {
    font-weight: 500;
  }
}

.full-width {
  width: 100%;
}
</style>
